package cn.wolfcode.luowowo.service.impl;

import cn.wolfcode.luowowo.domain.Destination;
import cn.wolfcode.luowowo.domain.Region;
import cn.wolfcode.luowowo.domain.Strategy;
import cn.wolfcode.luowowo.domain.StrategyCatalog;
import cn.wolfcode.luowowo.query.DestinationQuery;
import cn.wolfcode.luowowo.repository.DestinationRepository;
import cn.wolfcode.luowowo.service.IDestinationService;
import cn.wolfcode.luowowo.service.IStrategyCatalogService;
import cn.wolfcode.luowowo.service.IStrategyService;
import cn.wolfcode.luowowo.util.DBHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

@Service
//@Transactional
public class DestinationServiceImpl implements IDestinationService {
    //注入目的地接口
    @Autowired
    private DestinationRepository destinationRepository;
    //注入区域服务接口
    @Autowired
    private RegionServiceImpl regionService;
    //一般用于分页查询的接口
    @Autowired
    private MongoTemplate mongoTemplate;
    //注入攻略分类服务接口
    @Autowired
    private IStrategyCatalogService strategyCatalogService;

    //注入攻略服务接口
    @Autowired
    private IStrategyService strategyService;
    //增加
    @Override
    public void save(Destination destination) {
        destination.setId(null);
        destinationRepository.save(destination);
    }

    //删除
    @Override
    public void delete(String id) {
        destinationRepository.deleteById(id);
    }

    //更新
    @Override
    public void update(Destination destination) {
        destinationRepository.save(destination);
    }

    //查单个
    @Override
    public Destination get(String id) {
        return destinationRepository.findById(id).get();
    }

    //查全部
    @Override
    public List<Destination> listAll() {
        return destinationRepository.findAll();
    }

    //根据区域id查询关联的目的地集合
    @Override
    public List<Destination> getDestByRegionId(String rid) {
        //根据区域id查询区域对象
        Region region = regionService.get(rid);
        //从区域对象里那关联目的地id
        List<String> refIds = region.getRefIds();
        //根据关联目的地id查询目的地对象集合
        List<Destination> list = destinationRepository.findByidIn(refIds);
        return list;
    }

    //分页
    @Override
    public Page<Destination> query(DestinationQuery qo) {
        //创建查询对象
        Query query = new Query();
        //如果有关键字，就添加限制条件
        if (StringUtils.hasLength(qo.getKeyword())) {
            //创建限制条件
            Criteria criteria = Criteria.where("name").regex(".*" + qo.getKeyword() + ".*");
            //将限制条件添加到查询对象里
            query.addCriteria(criteria);
        }
        //判断是否有parentId，如果有就根据parentId查询，没有就根据null查询
        if (StringUtils.hasLength(qo.getParentId())) {
            query.addCriteria(Criteria.where("parentId").is(qo.getParentId()));
        } else {
            query.addCriteria(Criteria.where("parentId").is(null));
        }
        /*创建好分页信息和排序Pageable
         * 第一个参数是当前页面，只不过这个方法第一页是0
         * 第二个参数是一页显示多少条数据
         * 第三是排序，正序是ASC
         * 第三个参数是根据数据库的那一列排序
         * */
        Pageable pageable = PageRequest.of(qo.getCurrentPage() - 1, qo.getPageSize(), Sort.Direction.ASC, "_id");
        //     PageRequest.of(currentPage - 1, pageSize,Sort.Direction.ASC, "_id");
        //最后实现page的接口
        return DBHelper.query(mongoTemplate, Destination.class, query, pageable);
    }

    //吐司
    @Override
    public List<Destination> getToasts(String parentId) {
        //如果parentId为空就返回一个空集合
        if (!StringUtils.hasLength(parentId)) {
            return Collections.emptyList();
        }
        //先创建一个集合
        List<Destination> destinations = new ArrayList<>();
        //利用递归的方式，不停的调用自己寻找上级的方法
        this.creatToasts(destinations, parentId);
        //将集合反转
        Collections.reverse(destinations);
        return destinations;
    }

    @Override
    public List<Destination> search(String regionId) {
        //先创建一个空集合
        List<Destination> list = new ArrayList<>();
        //区分国内
        if ("-1".equals(regionId)) {
            //根据parentName是中国的查询省份
            list = destinationRepository.findByParentName("中国");
        } else {
            //区分国外
            //根据区域id先查出区域对象
            Region region = regionService.get(regionId);
            //在根据区域对象里的关联目的地集合查询，子目的地
            List<String> refIds = region.getRefIds();
            list = destinationRepository.findByIdIn(refIds);
        }
        //查询第二层
        //根据省份id去查，子目的地，可以通过子目的地的parentId去查
        for (Destination destination : list) {
            //只显示前5个数据
            Pageable pageable = PageRequest.of(0, 5, Sort.Direction.ASC, "_id");
            List<Destination> children = destinationRepository.findByParentId(destination.getId(), pageable);
            destination.setChildren(children);
        }

        return list;
    }

    //概况目录分类
    @Override
    public List<StrategyCatalog> catalogs(String destId) {
        //根据destId查询攻略分类对象，
        List<StrategyCatalog> strategyCatalogs = strategyCatalogService.queryCatalogByDestId(destId);
        //再通过攻略分类id查询攻略对象
        for (StrategyCatalog strategyCatalog : strategyCatalogs) {
            List<Strategy> strategy = strategyService.getStrategyByCatalogId(strategyCatalog.getId());
            //然后将攻略对象集合，放到攻略分类对象中的字段集合中
            strategyCatalog.setStrategies(strategy);
        }
        return strategyCatalogs;
    }

    @Override
    public List<Destination> list() {
        return destinationRepository.findAll();
    }


    //寻找目的地上级
    private void creatToasts(List<Destination> destinations, String parentId) {
        //根据parentId查询目的地
        Destination destination = this.get(parentId);
        //将目的地添加到集合中
        destinations.add(destination);
        //如果目的地还有parentId，就继续执行自己的方法
        if (StringUtils.hasLength(destination.getParentId())) {
            this.creatToasts(destinations, destination.getParentId());
        }
    }

    @Override
    public Destination getByName(String keyword) {
        return destinationRepository.findByName(keyword);
    }
}
